<?php

namespace IMT\Plugins\ParticipantsBundle\Controller;

use IMT\Plugins\ParticipantsBundle\Entity\ParticipantEvent;

use Symfony\Component\Routing\Exception\MethodNotAllowedException;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Acl\Model\AclProviderInterface;
use Symfony\Component\Security\Acl\Domain\ObjectIdentity;
use Symfony\Component\Security\Acl\Domain\UserSecurityIdentity;
use Symfony\Component\Security\Acl\Permission\MaskBuilder;
use IMT\UserBundle\Entity\GroupContact;
use IMT\AccountBundle\Entity\Account;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;


class DefaultController extends Controller
{
    
    public function indexAction()
    {
        return $this->forward('IMTPluginsParticipantsBundle:Default:show', array(
        	'idEvent' => 0
    	));
    }
    
    public function showAction($idEvent)
    {
    	$emEvent = $this->get('imt_event.event_manager');
    	$securityContext = $this->get('security.context');
    	$user = $securityContext->getToken()->getUser();
    	 
    	$participants = array();
    	
    	if($idEvent != 0){
    		$event = $emEvent->findEventBy(array('id' => $idEvent));
    		 
    		if(!$event)
    			throw $this->createNotFoundException('L\'événement recherché n\'existe pas');
    		
    		$participants = $event->getParticipants();
    	} else 
    		$event = $emEvent->createEvent();
    	    	 
    	return $this->render('IMTPluginsParticipantsBundle:Default:index.html.twig', array(
    			'participants' => $this->orderAllParticipants($participants),
    			'contacts' => $this->orderParticipants($user->getAccounts()),
    			'groups' => $this->orderParticipants($user->getGroupsContact()),
    			'event' => $event,
    	));
    }
    
    public function updateAJAXAction($idEvent)
    {
    	$return = array('result' => 500, 'msg' => 'Une erreur inconnue est survenue');
    
    	try {
    		$request = $this->getRequest();
    		$em = $this->getDoctrine()->getEntityManager();
			$aclProvider = $this->get('security.acl.provider');
			$securityContext = $this->get('security.context');
			$userManager = $this->get('fos_user.user_manager');
    		 
    		if('POST' == $request->getMethod()){
    
    			$emEvent = $this->container->get('imt_event.event_manager');
    			$validator = $this->get('validator');
    			 
    			if($idEvent != 0){
    				$event = $emEvent->findEventBy(array('id' => $idEvent));
    			}
    			 
    			if(!$event)
    				throw $this->createNotFoundException('L\'événement à modifier n\'existe pas');
    			
    			$repoParticipant = $this->getDoctrine()->getRepository('IMTPluginsParticipantsBundle:ParticipantEvent');
    			$repoContact = $this->getDoctrine()->getRepository('IMTUserBundle:Contact');
    			
    			$idContacts = $request->request->get('id_contacts');
    			$nbEdits = 0;
    			
    			// Recherche des participants déjà enregistrés et formation de la liste
    			$listParticipantResult = $repoParticipant->findBy(array(
    					"event" => $idEvent,
    			));
    			
    			$listParticipant = array();
    			foreach($listParticipantResult as $participant){
    				$listParticipant[$participant->getParticipant()->getId()] = $participant;
    			}
    			
    			// Récupération/Création ACL de l'event
    			$objectIdentity = ObjectIdentity::fromDomainObject($event);
    			$acl = $aclProvider->findAcl($objectIdentity);
    			if(!$acl)
    				$acl = $aclProvider->createAcl($objectIdentity);
    			
    			// Traitement des contacts envoyés
    			if(is_array($idContacts)){
	    			foreach($idContacts as $idContact){
		    			if(isset($listParticipant[$idContact])){
		    				$contact = $listParticipant[$idContact]->getParticipant();
		    				unset($listParticipant[$idContact]);
		    			} else {
		    				$contact = $repoContact->findOneBy(array("id" => $idContact));
			    			
			    			if(!$contact)
			    				throw $this->createNotFoundException('Un contact choisi n\'existe pas');
			    			
			    			$participantEvent = new ParticipantEvent();
			    			$participantEvent->setEvent($event);
			    			//$participantEvent->setAccount(NULL);
			    			$participantEvent->setParticipant($contact);
			    			$participantEvent->setParticipationState(0);
			    			
			    			$em->persist($participantEvent);
			    			$em->flush();
			    			
			    			$user = $contact->getUser();
			    			
			    			if($user){
			    				$securityIdentity = new UserSecurityIdentity($user, 'IMT\UserBundle\Entity\User');
			    							    				
			    				try {
			    					if(!$acl->isGranted(array(MaskBuilder::MASK_VIEW), array($securityIdentity))){
			    						throw new \Symfony\Component\Security\Acl\Exception\Exception();
			    					}
			    				} catch(\Symfony\Component\Security\Acl\Exception\Exception $e) {
			    					// Enregistrement ACL
					    			$acl->insertObjectAce($securityIdentity, MaskBuilder::MASK_VIEW);
			    				}
			    			}
			    			
			    			$nbEdits++;
		    			}
	    			}
    			}
    			 
    			// Récupération des aces de l'ACL
    			$aces = $acl->getObjectAces();
    			
    			foreach($listParticipant as $participantEvent){
	    			$em->remove($participantEvent);
	    			$em->flush();
	    			$nbEdits++;
      
	    			$user = $participantEvent->getParticipant()->getUser();
	    			
	    			if($user){
					    foreach($aces as $idAce => $ace){
					    	if($ace->getSecurityIdentity()->getUsername() == $user->getUsername()) {
					          	$acl->deleteObjectAce($idAce); 
					       	}			       
					    }
	    			}
    			}
    			
    			// Application des modifications ACLs
    			$aclProvider->updateAcl($acl);
    			
    			$return['result'] = 200;
    			$return['msg'] = ($nbEdits > 1) ? 'Les participants ont été modifiés' : (($nbEdits > 0) ? 'Le participant a été modifié' : 'Aucune modification apporté aux participants');
    			$return['nbEdits'] = $nbEdits;
    			/*$return['participant'] = array(
    					'state' => 0,
    					'contact' => $contact->getJsonObject(false)
    			);*/
    			return new Response(json_encode($return));
    		} else {
    			throw new MethodNotAllowedException('POST');
    		}
    	} catch(NotFoundHttpException $e){
    		return new Response(json_encode(array('result' => 500, 'msg' => $e->getMessage())));
    	} catch(AccessDeniedException $e){
    		return new Response(json_encode(array('result' => 500, 'msg' => $e->getMessage())));
    	} catch(\Exception $e){
    		return new Response(json_encode(array(
    				'result' => 500,
    				'msg' => 'Une erreur est survenue au niveau du serveur',
    				'debug' => $e->getMessage(),
    				'debug_stack' => $e->getTraceAsString()
    		)));
    	}
    	 
    	return new Response(json_encode($return));
    }
    
    public static function orderParticipants($groups)
    {
    	$indexs = array();
    	foreach($groups as $group){
    		if($group instanceof Account){
    			$account = $group;
    			
	    		foreach($account->getContacts() as $contact){
	    			if(!isset($indexs[$account->getId()]))
	    				$indexs[$account->getId()] = array('account' => $account, 'directory' => array());
	    			
	    			$count = 0;
	    			while(isset($indexs[$account->getId()]['directory'][$contact->getFirstName().$contact->getName().$count]) || $count == 0){
	    				if(!isset($indexs[$account->getId()]['directory'][$contact->getFirstName().$contact->getName().$count]))
	    					$indexs[$account->getId()]['directory'][$contact->getFirstName().$contact->getName().$count] = $contact;
	    				$count++;
	    			}
	    		}
	    		
	    		if(isset($indexs[$account->getId()]))
	    			ksort($indexs[$account->getId()]['directory']);
    		} else if($group instanceof GroupContact){
    			$groupContact = $group;
    			
	    		foreach($groupContact->getContacts() as $contact){
	    			if(!isset($indexs[$groupContact->getId()]))
	    				$indexs[$groupContact->getId()] = array('group' => $groupContact, 'directory' => array());
	    			
	    			$count = 0;
	    			while(isset($indexs[$groupContact->getId()]['directory'][$contact->getFirstName().$contact->getName().$count]) || $count == 0){
	    				if(!isset($indexs[$groupContact->getId()]['directory'][$contact->getFirstName().$contact->getName().$count]))
	    					$indexs[$groupContact->getId()]['directory'][$contact->getFirstName().$contact->getName().$count] = $contact;
	    				$count++;
	    			}
	    		}
	    		
	    		if(isset($indexs[$groupContact->getId()]))
	    			ksort($indexs[$groupContact->getId()]['directory']);
    		}
    	}
    	
    	return $indexs;
    }
    
    public static function orderAllParticipants($participants)
    {
    	$indexs = array(
    		'#' => array('title' =>'#', 'values' => array()),
    		'a' => array('title' =>'A', 'values' => array()),
    		'b' => array('title' =>'B', 'values' => array()),
    		'c' => array('title' =>'C', 'values' => array()),
    		'd' => array('title' =>'D', 'values' => array()),
    		'e' => array('title' =>'E', 'values' => array()),
    		'f' => array('title' =>'F', 'values' => array()),
    		'g' => array('title' =>'G', 'values' => array()),
    		'h' => array('title' =>'H', 'values' => array()),
    		'i' => array('title' =>'I', 'values' => array()),
    		'j' => array('title' =>'J', 'values' => array()),
    		'k' => array('title' =>'K', 'values' => array()),
    		'l' => array('title' =>'L', 'values' => array()),
    		'm' => array('title' =>'M', 'values' => array()),
    		'n' => array('title' =>'N', 'values' => array()),
    		'o' => array('title' =>'O', 'values' => array()),
    		'p' => array('title' =>'P', 'values' => array()),
    		'q' => array('title' =>'Q', 'values' => array()),
    		'r' => array('title' =>'R', 'values' => array()),
    		's' => array('title' =>'S', 'values' => array()),
    		't' => array('title' =>'T', 'values' => array()),
    		'u' => array('title' =>'U', 'values' => array()),
    		'v' => array('title' =>'V', 'values' => array()),
    		'w' => array('title' =>'W', 'values' => array()),
    		'x' => array('title' =>'X', 'values' => array()),
    		'y' => array('title' =>'Y', 'values' => array()),
    		'z' => array('title' =>'Z', 'values' => array()),
    	);
    	
    	foreach($participants as $participant){
    		$index = strtolower(substr(trim($participant->getParticipant()->getFirstname()), 0, 1));
    		$indexs[(isset($indexs[$index])) ? $index : '#']['values'][] = $participant; 
    	}
    	
    	foreach($indexs as $name => $index){
    		if(sizeof($index['values']) == 0) unset($indexs[$name]);
    	}
    	
    	return $indexs;
    }
    
//     public function addAJAXAction($idEvent)
//     {
//     	$return = array('result' => 500, 'msg' => 'Une erreur inconnue est survenue');
    	 
//     	try {
//     		$request = $this->getRequest();
//     		$em = $this->getDoctrine()->getEntityManager();
    			
//     		if('POST' == $request->getMethod()){
    			 
//     			$emEvent = $this->container->get('imt_event.event_manager');
//     			$validator = $this->get('validator');
    	
//     			if($idEvent != 0){
//     				$event = $emEvent->findEventBy(array('id' => $idEvent));
//     			}
    			
//     			if(!$event)
//     				throw $this->createNotFoundException('L\'événement à modifier n\'existe pas');
    			
//     			$repoContact = $this->getDoctrine()->getRepository('IMTUserBundle:Contact');
//     			$contact = $repoContact->findOneBy(array("id" => $request->request->get('id_contact')));
    			
//     			if(!$contact)
//     				throw $this->createNotFoundException('Le contact choisi n\'existe pas');
    			
//     			$participantEvent = new ParticipantEvent();
//     			$participantEvent->setEvent($event);
//     			//$participantEvent->setAccount(NULL);
//     			$participantEvent->setParticipant($contact);
//     			$participantEvent->setParticipationState(0);
//     			$em->persist($participantEvent);
//     			$em->flush();
    			 
//     			$event->addParticipantEvent($participantEvent);
//     			$emEvent->updateEvent($event);
    				 
//     			$return['result'] = 200;
//     			$return['msg'] = 'Le participant a été invité à l\'événement';
//     			$return['participant'] = array(
//     				'state' => 0,	
//     				'contact' => $contact->getJsonObject(false)
//     			);
//     			return new Response(json_encode($return));
//     		} else {
//     			throw new MethodNotAllowedException('POST');
//     		}
//     	} catch(NotFoundHttpException $e){
//     		return new Response(json_encode(array('result' => 500, 'msg' => $e->getMessage())));
//     	} catch(AccessDeniedException $e){
//     		return new Response(json_encode(array('result' => 500, 'msg' => $e->getMessage())));
//     	} catch(\Exception $e){
//     		return new Response(json_encode(array(
//     				'result' => 500,
//     				'msg' => 'Une erreur est survenue au niveau du serveur',
//     				'debug' => $e->getMessage()
//     		)));
//     	}
    	
//     	return new Response(json_encode($return));
//     }
    
//     public function removeAJAXAction($idEvent)
//     {
//     	$return = array('result' => 500, 'msg' => 'Une erreur inconnue est survenue');
    	
//     	try {
//     		$request = $this->getRequest();
//     		$em = $this->getDoctrine()->getEntityManager();
    		 
//     		if('POST' == $request->getMethod()){
    	
//     			$emEvent = $this->container->get('imt_event.event_manager');
//     			$validator = $this->get('validator');
    			 
//     			if($idEvent != 0){
//     				$event = $emEvent->findEventBy(array('id' => $idEvent));
//     			}
    			 
//     			if(!$event)
//     				throw $this->createNotFoundException('L\'événement à modifier n\'existe pas');
    			 
//     			$repoContact = $this->getDoctrine()->getRepository('IMTUserBundle:Contact');
//     			$contact = $repoContact->findOneBy(array("id" => $request->request->get('id_contact')));
    			 
//     			if(!$contact)
//     				throw $this->createNotFoundException('Le contact choisi n\'existe pas');
    			 
//     			$repoParticipant = $this->getDoctrine()->getRepository('IMTPluginsParticipantsBundle:ParticipantEvent');
//     			$participantEvent = $repoParticipant->findOneBy(array(
//     				"participant" => $request->request->get('id_contact'),
//     				"event" => $idEvent,
//     			));
    			 
//     			if(!$participantEvent)
//     				throw $this->createNotFoundException('Le contact choisi ne participe pas à l\'événement');
    			
//     			$em->remove($participantEvent);
//     			$em->flush();
    				
//     			$return['result'] = 200;
//     			$return['msg'] = 'Le contact a été supprimé de l\'événement';
//     			$return['participant'] = array(
//     					'state' => 0,
//     					'contact' => $contact->getJsonObject(false)
//     			);
//     			return new Response(json_encode($return));
//     		} else {
//     			throw new MethodNotAllowedException('POST');
//     		}
//     	} catch(NotFoundHttpException $e){
//     		return new Response(json_encode(array('result' => 500, 'msg' => $e->getMessage())));
//     	} catch(AccessDeniedException $e){
//     		return new Response(json_encode(array('result' => 500, 'msg' => $e->getMessage())));
//     	} catch(\Exception $e){
//     		return new Response(json_encode(array(
//     				'result' => 500,
//     				'msg' => 'Une erreur est survenue au niveau du serveur',
//     				'debug' => $e->getMessage()
//     		)));
//     	}
    	 
//     	return new Response(json_encode($return));
//     }
}
